package com.tcm.pay.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.exception.ServiceException;
import com.base.core.utils.R;
import com.tcm.pay.domain.dto.AggregatePayDTO;
import com.tcm.pay.domain.dto.PaymentDTO;
import com.tcm.pay.domain.dto.ScanPayDTO;
import com.tcm.pay.enums.BusinessCodeEnum;
import com.tcm.pay.enums.PayChannelEnum;
import com.tcm.pay.request.PayContext;
import com.tcm.pay.request.ScanAliPay;
import com.tcm.pay.request.WxAggregatePay;
import com.tcm.pay.request.WxMiniAuth;
import com.tcm.pay.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
public class PayService{

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private WxMiniAuth wxMiniAuth;

    private String aliAdviceUrl = "";

    private String wxAdviceUrl = "";

    public void setAliAdviceUrl(String aliAdviceUrl) {
        this.aliAdviceUrl = aliAdviceUrl;
    }

    public void setWxAdviceUrl(String wxAdviceUrl) {
        this.wxAdviceUrl = wxAdviceUrl;
    }

    /**
     * 支付宝扫码支付
     *
     * @param userId
     * @param orderId
     * @return
     * @throws Exception
     */
     public Map<String, Object> alipay(Long userId, Long orderId, String tradeType) throws ServiceException {

        PaymentDTO paymentDTO = null;
        try {
            paymentDTO = paymentService.findByOrderId(userId, orderId,tradeType);
        } catch (Exception e) {
            e.printStackTrace();
            R.throwFail(e.getMessage());
        }
        if (ObjectUtil.isEmpty(paymentDTO)) {
            R.throwFail(BusinessCodeEnum.ORDER_PAY_NOT_EXISTS);
        }
        if (paymentDTO.getStatus().equals(new Byte("1"))) {
            R.throwFail(BusinessCodeEnum.ORDER_PAID);
        }
        if (!paymentDTO.getPayChannel().equals(PayChannelEnum.ALIPAY.getCode().toLowerCase())) {
            R.throwFail(BusinessCodeEnum.ALIPAY_METHOD_WRONG);
        }
        ScanPayDTO scanPayDTO = new ScanPayDTO();
        scanPayDTO.setAdviceUrl(aliAdviceUrl);//回调地址
        scanPayDTO.setAmount(paymentDTO.getPayAmount().toString());
        scanPayDTO.setProducts(paymentDTO.getSubject());
        scanPayDTO.setBillNo(paymentDTO.getPaySn());
        scanPayDTO.setAmount(paymentDTO.getPayAmount().toString());
        PayContext payContext = new PayContext(new ScanAliPay());
        return payContext.pay(scanPayDTO);
    }

    /**
     *
     * @param userId
     * @param orderId
     * @param code
     * @return
     * @throws ServiceException
     */
    public Map<String, Object> wxpay(Long userId, Long orderId, String code, String tradeType) throws ServiceException {
        PaymentDTO paymentDTO = null;
        try {
            paymentDTO = paymentService.findByOrderId(userId,orderId, tradeType);
        } catch (Exception e) {
            e.printStackTrace();
            R.throwFail(e.getMessage());
        }
        if (ObjectUtil.isEmpty(paymentDTO)) {
            R.throwFail(BusinessCodeEnum.ORDER_PAY_NOT_EXISTS);
        }
        if (paymentDTO.getStatus().equals(new Byte("1"))) {
            R.throwFail(BusinessCodeEnum.ORDER_PAID);
        }
        if (!paymentDTO.getPayChannel().equals(PayChannelEnum.WEPAY.getCode().toLowerCase())) {
            R.throwFail(BusinessCodeEnum.WXPAY_METHOD_WRONG);
        }
        AggregatePayDTO aggregatePayDTO = new AggregatePayDTO();
        String openId = wxMiniAuth.authOpenId(code);
        //System.out.println("[openid]"+openId);
        aggregatePayDTO.setUserId(openId);
        System.out.println("[回调地址]"+ wxAdviceUrl);
        aggregatePayDTO.setAdviceUrl(wxAdviceUrl);//回调地址
        aggregatePayDTO.setAmount(paymentDTO.getPayAmount().toString());
        aggregatePayDTO.setSubject(paymentDTO.getSubject());
        aggregatePayDTO.setDesc(paymentDTO.getSubject());
        aggregatePayDTO.setMerchantOrderNo(paymentDTO.getPaySn());
        aggregatePayDTO.setAmount(paymentDTO.getPayAmount().toString());
        PayContext payContext = new PayContext(new WxAggregatePay());
        return payContext.pay(aggregatePayDTO);
    }

}
